import json
import socket
import configparser
import logging

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger('rpc_client')

class RPCClient:
    def __init__(self, host, port, username, password):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.next_id = 1

    def call(self, method, *params):
        """调用远程方法"""
        request = {
            'auth': {
                'username': self.username,
                'password': self.password
            },
            'method': method,
            'params': params,
            'id': self.next_id
        }
        self.next_id += 1

        try:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.connect((self.host, self.port))
                s.sendall(json.dumps(request).encode('utf-8'))
                response_data = s.recv(4096).decode('utf-8')
            
            response = json.loads(response_data)
            
            if 'error' in response and response['error'] is not None:
                raise RPCError(response['error']['code'], response['error']['message'])
            
            return response.get('result')
        except json.JSONDecodeError:
            raise RPCError(-32700, "Parse error")
        except Exception as e:
            raise RPCError(-32500, f"Transport error: {str(e)}")

class RPCError(Exception):
    """RPC 错误类"""
    def __init__(self, code, message):
        self.code = code
        self.message = message
        super().__init__(f"RPC error {code}: {message}")

if __name__ == "__main__":
    # 从配置文件加载配置
    config = configparser.ConfigParser()
    config.read('../config/config.ini')
    
    host = config.get('client', 'server_host', fallback='localhost')
    port = config.getint('client', 'server_port', fallback=8000)
    username = config.get('client', 'username', fallback='admin')
    password = config.get('client', 'password', fallback='')
    
    client = RPCClient(host, port, username, password)
    
    # 示例调用
    try:
        result = client.call('add', 5, 3)
        print(f"5 + 3 = {result}")
        
        result = client.call('division', 10, 2)
        print(f"10 / 2 = {result}")
        
        # 尝试除以零
        result = client.call('division', 10, 0)
        print(f"10 / 0 = {result}")
    except RPCError as e:
        print(f"RPC Error: {e}")
    
    # 系统命令调用示例
    try:
        result = client.call('system', 'ls -l')
        print("System command result:")
        print(result.get('stdout', ''))
    except RPCError as e:
        print(f"RPC Error: {e}")    
